﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using PBO.Data;

namespace PBO.Game.BattleClass
{
    public partial class Pokemon
    {
        public PokemonState State
        {
            get { return mState; }
            set
            {
                mState = value;
                if (value != PokemonState.Sleep)
                {
                    if (hypnosis)
                        hypnosis = false;
                    if (BattleState.nightmare)
                        BattleState.nightmare = false;
                }
                OnStateChanged();
            }
        }

        private PokemonBattleState mBattleState;
        public PokemonBattleState BattleState
        {
            get
            {
                if (mBattleState == null)
                    return PokemonBattleState.EmptyBattleState;
                return mBattleState;
            }
            set { mBattleState = value; }
        }

        private bool CanSetState(PokemonState stateValue, Pokemon target, bool showTrait, ref bool traitShowed)
        {
            if (State != PokemonState.No)
                return false;
            switch (stateValue)
            {
                case PokemonState.Poison:
                case PokemonState.Toxin:
                    if (this.HaveType(BattleType.Poison) || this.HaveType(BattleType.Steel))
                        return false;
                    if (GetSelTrait() == Trait.Immunity && (target == null || target.GetSelTrait() != Trait.MoldBreaker))
                    {
                        if (showTrait)
                        {
                            MyTeam.log.AppendMsg("CantPSN", this.GetNameString());
                            //MyTeam.log.AppendText(GetNameString() + "的免疫特性防止了中毒");
                            traitShowed = true;
                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    }
                    break;
                case PokemonState.Burn:
                    if (this.HaveType(BattleType.Fire))
                        return false;
                    if (GetSelTrait() == Trait.WaterVeil && (target == null || target.GetSelTrait() != Trait.MoldBreaker))
                    {
                        if (showTrait)
                        {
                            MyTeam.log.AppendMsg("CantBRN", this.GetNameString());
                            //MyTeam.log.AppendText(GetNameString() + "的水幕特性防止了烧伤");
                            traitShowed = true;
                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    }
                    break;
                case PokemonState.Freeze:
                    if (this.HaveType(BattleType.Ice) || MyTeam.ground.Weather == Weather.Sunny)
                        return false;

                    if (MyTeam.Pokemons.Any(p => p != null && p.State == PokemonState.Freeze))
                    {
                        MyTeam.log.AppendMsg("RULE_FRZ");
                        //MyTeam.log.AppendText(GetNameString() + "的队伍已有精灵被冻结", Color.Orange);
                        return false;
                    }

                    if (GetSelTrait() == Trait.MagmaArmor && (target == null || target.GetSelTrait() != Trait.MoldBreaker))
                    {
                        if (showTrait)
                        {
                            this.ShowTrait();
                            MyTeam.log.AppendMsg("CantFRZ", this.GetNameString());
                            //MyTeam.log.AppendText(GetNameString() + "的熔岩盔甲特性防止了冻结");
                            traitShowed = true;
                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    }
                    break;
                case PokemonState.Sleep:
                    if (MyTeam.ground.Uproar)
                        return false;

                    if (MyTeam.Pokemons.Any(p => p != null && p.hypnosis))
                    {
                        MyTeam.log.AppendMsg("RULE_SLP");
                        //MyTeam.log.AppendText(GetNameString() + "的队伍已有精灵被催眠", Color.Orange);
                        return false;
                    }

                    if ((GetSelTrait() == Trait.Insomnia || GetSelTrait() == Trait.VitalSpirit) && (target == null || target.GetSelTrait() != Trait.MoldBreaker))
                    {
                        if (showTrait)
                        {
                            this.ShowTrait();
                            MyTeam.log.AppendMsg("CantSLP", GetNameString());
                            traitShowed = true;
                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    }
                    break;
                case PokemonState.Paralysis:
                    if (GetSelTrait() == Trait.Limber && (target == null || target.GetSelTrait() != Trait.MoldBreaker))
                    {
                        if (showTrait)
                        {
                            this.ShowTrait();
                            MyTeam.log.AppendMsg("CantPAR", GetNameString());
                            traitShowed = true;
                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    }
                    break;
            }
            return true;
        }

        public bool SetState(PokemonState stateValue, Pokemon target = null, bool addlog = true, bool poisonSpike = false, bool itemEff = false, bool synchronize = false, bool showTraitEff = false)
        {

            if (MyTeam.Group.Safeguard && !itemEff)
                return false;
            if (GetSelTrait() == Trait.LeafGuard && MyTeam.ground.Weather == Weather.Sunny && !itemEff)
                return false;

            bool traitShowed = false;
            if (!CanSetState(stateValue, target, showTraitEff, ref traitShowed))
                return false;
            if (showTraitEff && traitShowed)
                return true;

            if (synchronize)
            {
                this.ShowTrait();
                if (stateValue == PokemonState.Toxin) stateValue = PokemonState.Poison;
                //MyTeam.log.AppendText(GetNameString() + "被传染了！");
                Battle.ChangeState(this, stateValue, MyTeam.log);
            }
            else if (poisonSpike)
            {
                MyTeam.log.AppendMsg("EnPSN", GetNameString());
                //MyTeam.log.AddText(GetNameString() + "因毒菱而中毒了");
            }
            SetState(stateValue, addlog, target);
            if (itemEff)
            {
                if (stateValue == PokemonState.Toxin)
                {
                    MyTeam.log.AppendMsg("ItemEnBadlyPSN", GetNameString(), Item.ToxicOrb);
                    //MyTeam.log.AddText(GetNameString() + "的剧毒珠使它中毒了！");
                    BattleState.toxinCounter = 0;
                }
                else if (stateValue == PokemonState.Burn)
                {
                    MyTeam.log.AppendMsg("ItemEnBRN", GetNameString(), Item.FlameOrb);
                    //MyTeam.log.AddText(GetNameString() + "的火珠使它烧伤了！");
                }
            }
            return true;
        }

        private void SetState(PokemonState stateValue, bool addLog, Pokemon target)
        {
            State = stateValue;
            switch (stateValue)
            {
                case PokemonState.Poison:
                    if (addLog) MyTeam.log.AppendMsg("EnPSN", GetNameString());
                    //MyTeam.log.AddText(GetNameString() + "中毒了！");
                    if (GetItem() == Item.PechaBerry)
                        RaiseItem();
                    break;
                case PokemonState.Toxin:
                    if (addLog) MyTeam.log.AppendMsg("EnPSN", GetNameString());
                    //MyTeam.log.AddText(GetNameString() + "中毒了！");
                    if (GetItem() == Item.PechaBerry)
                        RaiseItem();
                    BattleState.toxinCounter = 0;
                    break;
                case PokemonState.Burn:
                    if (addLog) MyTeam.log.AppendMsg("EnBRN", GetNameString());
                    //MyTeam.log.AddText(GetNameString() + "烧伤了！");
                    if (GetItem() == Item.RawstBerry)
                        RaiseItem();
                    break;
                case PokemonState.Paralysis:
                    if (addLog) MyTeam.log.AppendMsg("EnPAR", GetNameString());
                    //MyTeam.log.AddText(GetNameString() + "麻痹了！");
                    if (GetItem() == Item.CheriBerry)
                        RaiseItem();
                    break;
                case PokemonState.Freeze:
                    if (addLog) MyTeam.log.AppendMsg("EnFRZ", GetNameString());
                    //MyTeam.log.AddText(GetNameString() + "冻结了！");
                    if (GetItem() == Item.AspearBerry)
                        RaiseItem();
                    break;
                case PokemonState.Sleep:
                    if (addLog) MyTeam.log.AppendMsg("EnSLP", GetNameString());
                    //MyTeam.log.AddText(GetNameString() + "睡着了！");
                    int turn = MyTeam.random.Next(Battle.MinSleepTurn, Battle.MaxSleepTurn + 1);
                    sleepTurn = turn;
                    sleepCounter = 0;
                    hypnosis = true;
                    if (GetSelTrait() == Trait.EarlyBird)
                        sleepTurn /= 2;
                    if (GetItem() == Item.ChestoBerry)
                        RaiseItem();
                    break;
            }
            if (GetItem() == Item.LumBerry)
                RaiseItem();
            if (GetSelTrait() == Trait.Synchronize && target != null && stateValue != PokemonState.Freeze && stateValue != PokemonState.Sleep)
            {
                target.SetState(stateValue, null, true, false, false, true);
            }
        }

    }
}
